package com.aiprompt.demos.controller;

import com.aiprompt.demos.exception.ErrorCode;
import com.aiprompt.demos.exception.ThrowUtils;
import com.aiprompt.demos.manager.BigModelManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api/chat")
@CrossOrigin(origins = {"http://localhost:5173", "http://localhost:5174"}, allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.OPTIONS})
public class ChatStreamController {

    @Resource
    private BigModelManager bigModelManager;

    @Resource
    @Qualifier("aiTaskExecutor")
    private ThreadPoolTaskExecutor aiTaskExecutor;

    @Value("${api.key}")
    private String apiKey;

    @Value("${api.url}")
    private String apiUrl;

    /**
     * API配置检查接口
     */
    @GetMapping("/config")
    public Map<String, Object> checkConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put("apiUrl", apiUrl);
        config.put("apiKeyConfigured", apiKey != null && !apiKey.trim().isEmpty());
        config.put("apiKeyLength", apiKey != null ? apiKey.length() : 0);
        return config;
    }

    /**
     * 流式聊天接口
     */
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamChat(@RequestParam String message) {
        log.info("收到流式聊天请求: {}", message);
        ThrowUtils.throwIf(message == null || message.trim().isEmpty(), ErrorCode.PARAMS_ERROR, "消息不能为空");

        SseEmitter emitter = new SseEmitter(60000L); // 60秒超时

        // 使用线程池异步处理，避免阻塞主线程
        aiTaskExecutor.execute(() -> {
            try {
                // 调用AI生成流式响应（开始事件在BigModelManager中发送）
                bigModelManager.generateStreamResponse(
                    "你现在是一个提示词生成助手，请你根据用户发送的内容来生成一个有效高质量的提示词帮助用户解决问题",
                    message,
                    emitter
                );

            } catch (Exception e) {
                try {
                    emitter.send(SseEmitter.event()
                        .name("error")
                        .data("生成失败: " + e.getMessage()));
                    emitter.complete();
                } catch (IOException ioException) {
                    emitter.completeWithError(ioException);
                }
            }
        });
        
        return emitter;
    }

    /**
     * 普通聊天接口（兼容原有功能）
     */
    @PostMapping("/message")
    public SseEmitter chatMessage(@RequestBody ChatMessageRequest request) {
        ThrowUtils.throwIf(request == null || request.getMessage() == null, ErrorCode.PARAMS_ERROR);
        
        SseEmitter emitter = new SseEmitter(60000L);
        
        new Thread(() -> {
            try {
                bigModelManager.generateStreamResponse(
                    "你现在是一个提示词生成助手，请你根据用户发送的内容来生成一个有效高质量的提示词帮助用户解决问题",
                    request.getMessage(),
                    emitter
                );
                
            } catch (Exception e) {
                try {
                    emitter.send(SseEmitter.event()
                        .name("error")
                        .data("生成失败: " + e.getMessage()));
                    emitter.complete();
                } catch (IOException ioException) {
                    emitter.completeWithError(ioException);
                }
            }
        }).start();
        
        return emitter;
    }

    /**
     * 聊天消息请求DTO
     */
    public static class ChatMessageRequest {
        private String message;
        
        public String getMessage() {
            return message;
        }
        
        public void setMessage(String message) {
            this.message = message;
        }
    }
}
